#include "WaveGenerator.hpp"

void WaveGenerator::AddSample(short sample)
{
  m_samples.push_back(sample);
}

void WaveGenerator::Clear()
{
  m_samples.clear();
}

void WaveGenerator::GenerateData(long sampleRate)
{
  FillWaveInfo(sampleRate);

  // copy header
  m_data.assign(reinterpret_cast<char*>(&m_info), reinterpret_cast<char*>(&m_info + 1));

  // copy samples
  for (vector<short>::iterator it = m_samples.begin(); it != m_samples.end(); it++)
  {
    m_data.push_back(static_cast<char>(*it & 0xFF));
    m_data.push_back(static_cast<char>((*it >> 8) & 0xFF));
  }
}

char* WaveGenerator::GetData()
{
  ofstream ofs("c:\\test.wav", ios::binary);
  ofs.write(&m_data[0], m_data.size());
  ofs.close();

  return &m_data[0];
}

// filled according to https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
void WaveGenerator::FillWaveInfo(long sampleRate)
{
  memcpy(&m_info.m_chunkId,     "RIFF", sizeof(long));
  memcpy(&m_info.m_format,      "WAVE", sizeof(long));
  memcpy(&m_info.m_subChunk1Id, "fmt ", sizeof(long));
  memcpy(&m_info.m_subChunk2Id, "data", sizeof(long));

  m_info.m_subChunk1Size = 16;
  m_info.m_audioFormat   = 1;
  m_info.m_channels      = 1;
  m_info.m_bitsPerSample = 16;
  m_info.m_sampleRate    = sampleRate;
  m_info.m_blockAlign    = m_info.m_channels * m_info.m_bitsPerSample / 8;
  m_info.m_byteRate      = m_info.m_blockAlign * m_info.m_sampleRate;
  m_info.m_subChunk2Size = m_info.m_blockAlign * m_samples.size();
  m_info.m_chunkSize     = (m_info.m_subChunk2Size + 8) + (m_info.m_subChunk1Size + 8) + 4;
}